package Kerberos;

/* Simulation einer Kerberos-Session mit Zugriff auf einen Fileserver
 /* Client-Klasse
 */

import java.util.*;

public class Client extends Object {

	private KDC myKDC;

	private Server myFileserver;

	private String currentUser;

	private Ticket tgsTicket = null;

	private long tgsSessionKey; // K(C,TGS)

	private Ticket serverTicket = null;

	private long serverSessionKey; // K(C,S)

	// Konstruktor
	public Client(KDC kdc, Server server) {
		myKDC = kdc;
		myFileserver = server;
	}

	public boolean login(String userName, char[] password) {
		this.currentUser = userName;
		
		long t1		= this.generateNonce();
		long key	= this.generateSimpleKeyForPassword(password);
		
		Arrays.fill(password, ' ');
		
		TicketResponse tgsTicketResponse = this.myKDC.requestTGSTicket(userName, myKDC.getName(), t1);
		
		if (tgsTicketResponse.getNonce()!=t1)
			return false;
				
		if (!tgsTicketResponse.decrypt(key)){
			return false;
		}
		
		key = 0;
		
		this.tgsSessionKey = tgsTicketResponse.getSessionKey();
		
		this.tgsTicket = tgsTicketResponse.getResponseTicket();
		tgsTicketResponse.print();
		
		return true;
	}

	public boolean showFile(String serverName, String filePath) {
		if (this.tgsTicket==null){
			return false;
		}

		
		Auth tgsAuth = new Auth(this.currentUser, (new Date()).getTime());
		tgsAuth.encrypt(tgsSessionKey);
		
		if (this.serverTicket==null) {
			long t2 = this.generateNonce();
			
			TicketResponse serverTicketResponse = this.myKDC.requestServerTicket(this.tgsTicket, tgsAuth, serverName, t2);
			
			if (!serverTicketResponse.decrypt(this.tgsSessionKey)){
				serverTicket.printError("Error");
				return false;
			}
			
			this.serverSessionKey = serverTicketResponse.getSessionKey();
			
			this.serverTicket = serverTicketResponse.getResponseTicket();
			serverTicketResponse.print();
		}
		
		Auth srvAuth = new Auth(this.currentUser, (new Date()).getTime());
		srvAuth.encrypt(this.serverSessionKey);
		
		return this.myFileserver.requestService(this.serverTicket, srvAuth, "showFile", filePath);
	}

	/* *********** Hilfsmethoden **************************** */

	private long generateSimpleKeyForPassword(char[] pw) {
		// Liefert einen Schluessel fuer ein Passwort zurueck, hier simuliert als
		// long-Wert
		long pwKey = 0;
		for (int i = 0; i < pw.length; i++) {
			pwKey = pwKey + pw[i];
		}
		return pwKey;
	}

	private long generateNonce() {
		// Liefert einen neuen Zufallswert
		long rand = (long) (100000000 * Math.random());
		return rand;
	}
}
